'''

'''
import os
import pathlib
import sys

root_path = str(pathlib.Path(os.path.abspath(__file__)).parent.parent)
sys.path.append(root_path)

import numpy as np
# from sklearn.experimental import enable_iterative_imputer
from sklearn import impute
# import fancyimpute as fyi
import preprocess.preprocess_expand as exp
from utils.util import back_args_str, auto_pate
import pandas as pd


class Preprocesstype(object):
    def __init__(self, type):
        self.type = type

    def fit(self, X, y):
        return self

    def transform(self, X):
        if self.type == 'category':
            X = X.astype(str)
        else:
            X = X.apply(pd.to_numeric)
        self.columns = X.columns.tolist()
        return X

    # def get_feature_names(self):
    #     return self.columns


class PreprocessMissvalue(object):
    def __init__(self, method='SimpleImputer()'):
        '''
        :param method:
        1.SimpleImputer
        parameters for SimpleImputer:
            - strategy: mean, median, constant, most_frequent
            - fill_value: When strategy == "constant", fill_value is used to replace all
        occurrences of missing_values.
            - add_indicator: add binary indicators for missing values

        2.IterativeImputer - from fancyimpute or scikit-learn 0.22-version
        parameters for IterativeImputer:
            - max_iter: Maximum number of imputation rounds to perform before returning the imputations computed during the final round.
            - add_indicator: add binary indicators for missing values

        3.KNNImputer - from scikit-learn 0.22-version
        parameters for KNNImputer:
            - n_neighbors : Number of neighboring samples to use for imputation.

        '''
        self.extra = False
        try:
            self.method = eval(f"impute.{auto_pate(method)}")
        except Exception as e:
            self.extra = True
        if self.extra:
            self.extra = False
            # try:
            #     self.method = eval(f"fyi.{auto_pate(method)}")
            # except Exception as e:
            #     self.extra = True

            if self.extra:
                try:
                    self.method = eval(f"exp.{auto_pate(method)}")
                except Exception as e:
                    raise AttributeError('传入的方法名或者参数不对，无法实例化对象')

    def fit(self, *args, **kwargs):
        return self.method.fit(*args, **kwargs)

    def transform(self, *args, **kwargs):
        return self.method.transform(*args, **kwargs)


class PreprocessOutlier(object):
    def __init__(self, method='Replace()'):
        try:
            self.method = eval(f"exp.{auto_pate(method)}")
        except Exception as e:
            raise AttributeError('传入的方法名或者参数不对，无法实例化对象')

    def fit(self, *args, **kwargs):
        return self.method.fit(*args, **kwargs)

    def transform(self, *args, **kwargs):
        return self.method.transform(*args, **kwargs)
